																一、登录功能
<!-- 1.在commponts目录中新建一个login.vue -->
<div>
	<template>
		<div class="login_contail">
			<div class="login_content">
				<!-- 头像区域 -->
				<div class="login_image">
					<img src="../assets/logo.png" alt="">
				</div>
				<!-- 登录表单区域  v-bind动态绑定属性model(数据对象属性)Formdata-->
				<el-form  label-width="0px" class="form_content" :model="Formdata" :rules="FormdataRules"  ref="FormdataRef">
					<!-- 输入框区域 -->
				  <el-form-item prop="username">
					  <!-- main.js中引入自己下载好的字体图标iconfont.css，然后打开demo_fontclass.html页面，找到自己想要的字体图标iocn -->
				    <el-input prefix-icon="iconfont icon-user" v-model="Formdata.username"></el-input>
				  </el-form-item>
				  <el-form-item prop="password">
				    <el-input prefix-icon="iconfont icon-3702mima"  v-model="Formdata.password" type="password"></el-input> <!-- type="password表示把类型转换成密码型，数字将会被点代替 -->
				  </el-form-item>
					<!-- 按钮区域 -->
					<el-form-item class="form_btn">
						<el-button class="form_button" type="primary"  @click="loginForm">登录</el-button>
						<el-button class="form_button" type="info" @click="resetForm('FormdataRef')">重置</el-button>
					</el-form-item>
				</el-form>
			</div>
		</div>
	</template>
	
	<script>
		export default {}
	</script>
	
	<!-- 1.绑定表单数据
			在表单上绑定     动态绑定属性:model  ，javascript中返回绑定值，输入框中双向绑定对象属性  -->
	<style lang="less" scoped>
		// 先在assets公共目录中新建goble.css给html和body和app给高度为100%，然后设置login_contail的高度为100%，盒子就撑开了，外面的颜色就沾满整个屏幕
		.login_contail{
			height: 100%;
			background-color: #2b4b6b;
		}
		.login_content{
			height: 300px;
			width: 500px;
			background-color: white;
			border-radius: 5px;
			position: absolute;
			top: 50%;
			left: 50%;
			transform: translate(-50%,-50%);
			
			.login_image{
				height: 100px;
				width: 100px;
				border: 1px solid white;
				border-radius: 50%;
				padding: 10px;
				position: absolute;
				left: 50%;
				top: 0%;
				transform: translate(-50%,-50%);
				background-color: #FCFFFC;
				box-shadow: 0 0 15px;
				img{
					width: 100%;
					height: 100%;
					border-radius: 50%;
					background-color:#ECEEEB ;
				}
			}
			.form_content{
				padding: 100px 10px 0px 10px;
				width: 100%;
				box-sizing: border-box;
				/* 按钮右边对齐，则设置为横轴弹性布局，然后尾部对齐，就靠右边了 */
				.form_btn{
					display: flex;
					justify-content: flex-end;
				}
			}
		}
	</style>
</div>

<!-- 2.assets目录中新建goble.css全局样式并在main.js中引入这个css -->
<div>
	// 导入全局样式
	import './assets/goble.css'
</div>

<!--3.在路由index.js中引入 login.vue组件 ，并配置路由规则-->
<div>
	import Vue from 'vue'
	import VueRouter from 'vue-router'
	import Login from '../commponts/login.vue'
	
	Vue.use(VueRouter)
	
	const routes = [
		{ path: '/', redirect: '/login' },
		{ path: '/login', component: Login }
	]
	
	const router = new VueRouter({
	  routes
	})
	export default router
	
</div>

<!-- 4.根组件中添加路由占位符，login组件中的内容全部现在在路由占位符中 -->
<div>
	<template>
	  <div id="app">
	   <router-view></router-view>
	  </div>
	</template>
</div>

<!-- 5.表单数据绑定    登录表单区域  v-bind动态绑定属性model(数据对象属性)Formdata-->
<div>
	<el-form :model="Formdata">
		<!-- 输入框区域 -->
	  <el-form-item>
	    <el-input v-model="Formdata.username"></el-input>
	  </el-form-item>
	  <el-form-item>
	    <el-input  v-model="Formdata.password" ></el-input> 
	  </el-form-item>
	</el-form>
	<!-- ② -->
	<script>
		export default {
			data(){
				return {
					// 这是登录表单的数据绑定对象
					Formdata:{
						username:'admin',
						password:'123456'
					}
	</script>
</div>


<!-- 6.数据表单验证    Form 组件提供了表单验证的功能，只需要通过 rules 属性传入约定的验证规则，并将 Form-Item 的 prop 属性设置为需校验的字段名即可-->
<div>
	<el-form :rules="FormdataRules">
		<!-- 输入框区域 -->
	  <el-form-item prop="username">
	    <el-input></el-input>
	  </el-form-item>
	  <el-form-item prop="password">
	    <el-input></el-input> 
	  </el-form-item>
	</el-form>
	
	data(){
		return {
			//这是登录表单的验证规则对象
			// Form 组件提供了表单验证的功能，只需要通过 rules 属性传入约定的验证规则，并将 Form-Item 的 prop 属性设置为需校验的字段名即可
			FormdataRules:{
				uname:[
					 { required: true, message: '请输入用户名称', trigger: 'blur' },
					 { min: 3, max: 10, message: '长度在 3 到 10个字符', trigger: 'blur' }
				],
				password:[
					{ required: true, message: '请输入密码', trigger: 'blur' },
					{ min: 6, max: 15, message: '长度在 6到 15个字符', trigger: 'blur' }
				]
			}
		}
	}
</div>


<!-- 7.表单重置 -->
<div>
	<!-- 按钮区域 -->
	<el-form-item class="form_btn">
		<el-button class="form_button" type="info" @click="resetForm('FormdataRef')">重置</el-button>
	</el-form-item>
	
	methods:{
		// 表单重置  el-form中需要ref获取引用对象  this就是当前页面的表单组件login.vue这个实例对象 this.$refs[formName]就是表单实例对象el-form
		// resetFields 重置
		 resetForm(formName) {
		        this.$refs[formName].resetFields();
		      },
</div>

<!-- 8.登录前预验证 -->
<div>
	<!-- 按钮区域 -->
	<el-form-item class="form_btn">
		<el-button class="form_button" type="primary"  @click="loginForm">登录</el-button>
	</el-form-item>
	
	methods:{
		//表单预验证  el-form中需要ref获取引用对象
		// validate 验证  Function(callback: Function(boolean, object))   validate(回调函数，布尔值)
		loginForm(){ 
			this.$refs.FormdataRef.validate()
			}
	}
</div>

<!-- 9.验证通过后发送axios请求 -->
<div>
	1.main.js中全局配置axios
		//全局配置axios   1.引入axios  2.把axios挂载到vue上，$http这个名称可以自定义  使用axios时候直接this.$http
		import axios from 'axios'
		// 默认地址
		axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
		Vue.prototype.$http = axios
	
	2.login.vue中
		loginForm(){
											// 一
			this.$refs.FormdataRef.validate(async valid=>{
				// 要使用axios发送请求，需要先下载axios开发依赖，然后main.js中全局配置axios
				// 如果为假false  则不发送axios请求
											// 二
				if (!valid) return;
				// 验证成功为真，则发送axios请求 返回的是一个pormise对象，需要await
				let {data:res} =await this.$http.post('login',this.Formdata)
				// console.log(data.data)
			});
		}
</div>

<!-- 10.配置登录成功或失败的 弹窗-->
<div>
	loginForm(){
										// 一
		this.$refs.FormdataRef.validate(async valid=>{
			// 要使用axios发送请求，需要先下载axios开发依赖，然后main.js中全局配置axios
			// 如果为假false  则不发送axios请求
										// 二
			if (!valid) return;
			// 验证成功为真，则发送axios请求 返回的是一个pormise对象，需要await
			let {data:res} =await this.$http.post('login',this.Formdata)
			// console.log(data.data)
			
			
			if (res.meta.status != 200) return this.$message.error('登录失败')
			this.$message.success('登录成功')
		});
	}
</div>

<!-- 11.登录成功后，token保存在客户端sessionStorage中 -->
<div>
	loginForm(){
										// 一
		this.$refs.FormdataRef.validate(async valid=>{
			// 要使用axios发送请求，需要先下载axios开发依赖，然后main.js中全局配置axios
			// 如果为假false  则不发送axios请求
										// 二
			if (!valid) return;
			// 验证成功为真，则发送axios请求 返回的是一个pormise对象，需要await
			let {data:res} =await this.$http.post('login',this.Formdata)
			// console.log(data.data)
			if (res.meta.status != 200) return this.$message.error('登录失败')
			this.$message.success('登录成功')
										// 三
			// 登录成功后的token保存在客户端的sessionStorage中
			window.sessionStorage.setItem("token",res.data.token)
			//通过编程式导航跳转到后台主页，路由地址是/home
			this.$router.push('/home')
			
			//1. localStorage是本地持久化存储     sessionStorage是浏览器会话期间存储
			//2. 为什么要保存token
					// 2.1 原因是：项目中除了登录之外的其他API接口，必须在登录之后才能访问；
					// 2.2另外：token只应在当前网页打开期间生效，所以将token保存在sessionStorage中
		});
	}
</div>

<!-- 12.路由守卫   判断有没有登录就访问了后台界面 -->
<div>
	路由index.js中
		//挂载路由导航守卫
		router.beforeEach((to,from,next)=>{
			//to 将要访问的路径
			//from 代表从哪个路劲跳转而来
			//next 是一个函数，表示放行
				// next()放行      next('/login')强制跳转到login界面
			if (to.path === '/login') return next()
			//如果路由地址不是登录界面，则 获取token
			const tokenStr = window.sessionStorage.getItem('token')
			// 判断token是否在，没有token则自动跳转到登录界面
			if (!tokenStr) return next('/login')
			next()
		})
		
</div>

<!-- 13.退出功能   实质就是清除token，然后跳转到登录界面 -->
<div>
	1.commponts文件夹中新建home.vue
		<template>
			<div>
				<el-button type="info" @click="outinfo">退出</el-button>
			</div>
		</template>
		
		<script>
			export default{
				methods:{
					//退出功能   基于token退出只需要清除token,然后跳转到登录界面
					outinfo(){
						window.sessionStorage.clear()
						// 跳转到登录界面
						this.$router.push('/login')
					}
				}
			}
		</script>
	2.路由index.js中导入home.Vue
		import Home from '../commponts/home.vue'
		
		const routes = [
			{ path: '/home', component: Home },
		]
</div>

															<!-- 代码上传到码云上 -->
	<div>
		1.git status                          查看源代码状态（上面红的是以前的，下面红的是新增的文件）
		2.git add . 						  所有文件放到缓存区
		3.git status     					  此时为绿色，已经把代码放到了缓存区
		4.git commit -m "完成了登录功能"		  将缓存区代码提交到了本地存储中
		5.git branch    				      查看分支（前面*表示此时在这个分支）
		6.将分支合并到master主分支上
			1）git checkout master 			  切换到master主分支
			2) git branch 					  查看当前处于哪个分支（master）
			3）git merge login       		  合并代码 （将login的代码合并到master主分支上）
		7.git push 							  将本地master分支推送到码云上
		8.打开码云官网=》仓库-》当前项目分支（查看）   当前只有主分支，login分支没有在上面
		9.git checkout login     			  切换到login分支
		10.git branch                        查看在哪个分支
		11.git push -u origin login          将login分支推送到码云上（本地login分支推送到码云origin仓储里，名字叫login）
	</div>




														<!-- home.vue -->
<!-- 1.通过axios请求拦截器添加token验证（此时需要提供一个authorization字段提供token令牌） -->
<div>
		main.js中配置请求拦截器：
			//axios请求拦截器
			axios.interceptors.request.use(config => {
				//为请求头对象，添加token验证的Authorization字段
				config.headers.Authorization = window.sessionStorage.getItem('token')
				return config
			})
</div>

<!-- 2.获取左侧菜单数据 -->
<div>
	当页面打开后立即获取左侧菜单数据，所以需要添加生命周期函数created()
		<script>
			export default{
				data(){
					return {
						// 第三步：
						MenuList:[]
					}
				},
				//第一步： 当页面打开后立即获取左侧菜单数据，所以需要添加生命周期函数
				created(){
					this.getMenuList()
				},
				methods:{
					//第二步： axios请求获取左侧菜单数据,axios返回的是Promise对象，所以await
					async getMenuList(){
						// 数据在data里面，所以结构data，重命名为res
						// 获取数据之后要显示在页面上，所以上面data里面需要接收这些数据
						const {data:res} = await this.$http.get('menus')
						console.log(res)
						if (res.meta.status != 200) return this.$message.error(res.meta.msg)
						this.MenuList = res.data
					}
				}
			}
		</script>
		<!-- 第四步：双层for循环渲染左侧菜单数据 -->
		<!-- 一级菜单 -->
		<!-- 这里动态绑定属性index -->
		<el-submenu  v-for="item in MenuList" :key="item.id">
							   <!-- 一级菜单模板区域 -->
		  <template slot="title">
								 <!-- 图标 -->
		    <i class="iconfont" :class="icons[item.id]"></i>
							   <!-- 文本 -->
		    <span>{{item.authName}}</span>
		  </template>
							 
							 <!-- 二级菜单 -->
		  <el-menu-item-group>
		    <el-menu-item  v-for="subitem in item.children" :key="subitem.id">
								  <!-- 一级菜单模板区域 -->
								  <template slot="title">
								  		 <!-- 图标 -->
								    <i class="el-icon-menu"></i>
								    <!-- 文本 -->
								    <span>{{subitem.authName}}</span>
								  </template>
							    </el-menu-item>
		  </el-menu-item-group>
		</el-submenu>
</div>

<!-- 3.首页路由重定向 -->
<div>
	index.js中
		const routes = [
			{ 
				path: '/home', 
				component: Home,
				redirect:'/Welcome',
				children:[
					{ path: '/welcome',component:Welcome}
				]
			},
		]
</div>

<!-- 4.侧边栏路由链接 -->
<div>
	home.vue中
		<!-- router:是否使用 vue-router 的模式，启用该模式会在激活导航时以 index 作为 path 进行路由跳转 -->
						<el-menu
						   :router="true">
							 <!-- 二级菜单 -->
		        <el-menu-item-group>
		          <el-menu-item :index="'/'+ subitem.path" v-for="subitem in item.children" :key="subitem.id">
								  <!-- 一级菜单模板区域 -->
								  <template slot="title">
								  		 <!-- 图标 -->
								    <i class="el-icon-menu"></i>
								    <!-- 文本 -->
								    <span>{{subitem.authName}}</span>
								  </template>
							    </el-menu-item>
		        </el-menu-item-group>
		    </el-menu>
</div>

<!--  -->

															<!-- users.vue  二级菜单   用户列表 -->
<!-- 1.新建users.vue,并配置路由在home.vue下 -->
<!-- 2.设置点击二级菜单用户列表时高亮显示       (就是点击用户列表时,会有高亮,而且刷新之后高亮继续在上一次点击高亮的地方) -->
<div>
	需要保持上一次高亮的样子,就需要使用   NavMenu 导航菜单  的el-menu里面添加default-active         
		default-active:（值为string类型），el-menu-item中当前激活菜单的 index（其实就是路由复制给index，之后我们点击路由后，就可以引起高亮） (点击二级菜单高亮显示)
			1. <el-menu :default-active="activepath">  <!-- activepath存放的是当前二级菜单路由的地址 -->
				2.<el-menu-item :index="'/'+ subitem.path" @click="defaultActive('/'+ subitem.path)">
			3.data(){
				return {
					//存放的是点击二级菜单地址（高亮状态下的二级菜单地址）
					activepath:''
				}
			},
			// 当页面打开后立即获取左侧菜单数据，所以需要添加生命周期函数
			created(){
				// 4.当页面打开，之前我们点击路由后，当前二级菜单可以继续引起高亮
				this.activepath = window.sessionStorage.getItem('activepath')
			},
			methods:{
				// 5.点击高亮，二级菜单的index路由地址存储在本地（sessionStorage）中，然后在将本地的数据存储在default-active中
					defaultActive(path){
						window.sessionStorage.setItem('activepath',path)
						this.activepath = path
					}
				}
</div>

<!-- 3. 用户列表右侧的布局-->
<!-- 4.表格中获取用户列表数据 -->
<div>
	1.1)在data中声明一个私有成员变量userlist存储列表数据
	  2)// <!-- 用户列表请求的参数   query:查询参数  pagenum:当前页码  pagesize:每页显示条数-->
				queryInfo:{
					query: '',
					pagenum: 1,
					pagesize: 2
				}
	2.created生命周期函数中：this.getUserList()
	3.methods中发送请求，请求获取列表数据
		methods:{
			async getUserList(){
				let {data:res} = await this.$http.get('users',{params:this.queryInfo})
				//操作: 退出登录,重新进来,然后点击用户列表,就会出现object对象,就是请求回来的数据
				console.log(res)
				// 获取数据成功后就渲染到页面上
				if (res.meta.status != 200) return this.$message.error(res.meta.status)
				this.userlist = res.data.users
				this.total = res.data.total
			},
		}
	3.渲染到页面上
	当el-table元素中注入data对象数组后，在el-table-column中用prop属性来对应对象中的键名即可填入数据，用label属性来定义表格的列名
		type	对应列的类型。如果设置了 selection 则显示多选框；如果设置了 index 则显示该行的索引（从 1 开始计算）；如果设置了 expand 则显示为一个可展开的按钮 -->
			<el-table :data="userlist" style="width: 100%" border>
				  <el-table-column type="index"></el-table-column>
			      <el-table-column prop="username" label="姓名"></el-table-column>
				  <el-table-column prop="email" label="邮箱"></el-table-column>
				  <el-table-column prop="mobile" label="电话"></el-table-column>
				  <el-table-column prop="role_name" label="角色"></el-table-column>
				  <el-table-column label="状态"></el-table-column>
				  <el-table-column label="操作"></el-table-column>
			</el-table-column>
	4.状态区域设置开关
		// 因为状态为true,而要显示开关形式,所以不能直接prop来获取  // el-switch 绑定v-model到一个Boolean类型的变量
		// 这里需要用到作用域插槽(父组件对子组件的内容进行加工处理),使用template加上slot-scope="scope"
		<el-table-column label="状态">
							<template slot-scope="scope">
								<!-- scope.row:获取这一行的数据(这个角色的所有数据) -->
								<!-- change事件:switch 状态发生变化时的回调函数	获得新状态的值 (修改用户状态(修改需要发送请求),为了刷新后继续是上一次开关的样子)-->
								<el-switch  v-model="scope.row.mg_state" @change="switchUserState(scope.row)"></el-switch>
							</template>
		</el-table-column>
		// 监听switchUserState开关状态
		async switchUserState(row){
			// ${row.id}  ${}:输出值  
			let {data:res} = await this.$http.put(`users/${row.id}/state/${row.mg_state}`)
			console.log(res)
			if (res.meta.status !== 200){
				row.mg_state = !row.mg_state
				return this.$message.error(res.meta.msg)
			}
			this.$message.success(res.meta.msg)
		},
	5.操作区域
		<!-- 通过作用域插槽渲染操作数据 -->
		<el-table-column label="操作">
							  <!-- 通过slot-scope来获取作用域插槽数据scope -->
							  <template  slot-scope="scope">
								    <!-- 修改按钮 -->
								    <el-button type="primary" icon="el-icon-edit" size="mini"></el-button>
									<!-- 删除按钮 -->
									<el-button type="danger" icon="el-icon-delete" size="mini"></el-button>
									<!-- tooltip文字提示 -->
									<el-tooltip effect="dark" content="分配角色" placement="top"  :enterable="false">
									      <!--分配角色按钮    :enterable="false"鼠标离开文字提示消失-->
									      <el-button type="warning" icon="el-icon-setting" size="mini" @click="showSetRoleDialog(scope.row)"></el-button>
									</el-tooltip>
							  </template>
		</el-table-column> 
</div>

<!-- 5. 分页区域-->
<div>
	1.<el-pagination
	      @size-change="handleSizeChange"
	      @current-change="handleCurrentChange"
	      :current-page="queryInfo.pagenum"  
	      :page-sizes="[1, 2, 5, 7]"
	      :page-size="queryInfo.pagesize"  
	      layout="total, sizes, prev, pager, next, jumper"
	      :total="total">
	  </el-pagination>
	2.// 监听pagesize改变的事件
			handleSizeChange(newsize){
				// 获取当前选择的pagesize
				// console.log(newsize)
				// 改变data中pagesize的值
				this.queryInfo.pagesize = newsize
				// 重新发送修改请求
				this.getUserList()
			},
			// 监听页码值改变的事件
			handleCurrentChange(page){
				// console.log(page)
				this.queryInfo.pagenum = page
				this.getUserList()
			},
</div>

<!-- 6.输入框区域事件 -->
<div>
	1.<!-- clear事件	在点击由 clearable 属性生成的清空按钮时触发(清空输入内容，并且自动显示所有数据) -->
				  <el-input placeholder="请输入内容" v-model="queryInfo.query" clearable @clear="clearSearch">
				      <el-button slot="append" icon="el-icon-search"  @click="searchUsers"></el-button>
				  </el-input>
	2.// 清除input内容
			clearSearch(){
				// 当前查询参数为空
				this.queryInfo.query = ''
				// 当前页面保持第一页
				this.queryInfo.pagenum = 1
				this.getUserList()
			},
			// 点击搜索按钮
			searchUsers(){
				// 当前页码为第一页
				this.queryInfo.pagenum = 1
				this.getUserList()
			}
</div>

<!-- 7.添加用户对话框 -->
<div>
	1.<!-- 添加用户按钮 ref 绑定控件，$refs 获取控件   rules：表单验证规则 :model绑定表单数据对象	-->
		<!--el-form中 rules：表单验证规则  el-form-item中 prop 属性设置为需校验的字段名即可 -->
	<el-dialog title="添加用户"  :visible.sync="dialogVisible" width="50%" @close="addformclose">
	  <el-form ref="AddformRef" :model="Addform" label-width="80px" :rules="addformrules">
	    <el-form-item label="用户名" prop="username">
	      <el-input v-model="Addform.username"></el-input>
	    </el-form-item>
		<el-form-item label="密码"  prop="password">
		  <el-input v-model="Addform.password"></el-input>
		</el-form-item>
		<el-form-item label="邮箱"  prop="email">
		  <el-input v-model="Addform.email"></el-input>
		</el-form-item>
		<el-form-item label="手机号"  prop="mobile">
		  <el-input v-model="Addform.mobile"></el-input>
		</el-form-item>
	 </el-form>
	  <span slot="footer">
	    <el-button @click="dialogVisible = false" >取 消</el-button>
	    <el-button type="primary" @click="addUser">确 定</el-button>
	  </span>
	</el-dialog>
	
	2.用户数据对象和用户表单验证
	data中：// 添加用户对话框是否显示
				dialogVisible: false,
				// 添加用户表单数据对象
				Addform:{
					username:'',
					password:'',
					email:'',
					mobile:''
				},
				// 添加用户表单验证
				addformrules:{
					username:[{required:true,message:'请输入用户名',trigger:'blur'},
							  {min:3,max:10,message:'请输入3-10个字符',trigger:'blur'}],
					password:[{required:true,message:'请输入密码',trigger:'blur'},
						      {min:6,max:15,message:'请输入6-15个字符',trigger:'blur'}],
					email:[{required:true,message:'请输入邮箱地址',trigger:'blur'},
						   {validator:checkEmail,trigger:'blur'}],
					mobile:[{required:true,message:'请输入手机号码',trigger:'blur'},
						    {validator:checkMobile,trigger:'blur'}]
				}
		3.// 自定义验证规则（邮箱和手机号），然后验证规则处通过validator来接收验证变量
			// 邮箱的（定义一个变量来接收）rule:验证规则,value:需要验证的值,callback
			var checkEmail = ((rule,value,callback)=>{
				var reg =  /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
				if (reg.test(value)){
					callback()
				}else{
					callback(new Error('请输入正确的邮箱地址'))
				}
			})
			// 手机号码的
			var checkMobile = (rule,value,cb)=>{
				var reg =  /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
				if (reg.test(value)){
					callback()
				}else{
					callback(new Error('请输入正确的手机号码'))
				}
			}
		4.重置（取消）<!-- 重置操作 1.当对话框关闭后2.第二次打开没有记录   close事件中调用resetFields()即可清空重置 -->
			<el-dialog title="添加用户"  :visible.sync="dialogVisible" width="50%" @close="addformclose">
			methods:{
				addformclose(){
					//resetFields清空
					this.$refs.AddformRef.resetFields()
				}
			}
		5.//表单预验证  validate（）函数   需要请求添加用户接口
		    <el-button type="primary" @click="addUser">确 定</el-button>
			methods:{
				async addUser(){
					//表单预验证  validate（）函数  在函数里面valid进行验证，验证结果valid为true预验证通过
					//验证成功后需要请求添加用户接口
					this.$refs.AddformRef.validate(async valid =>{
						if (!valid)return
						let {data:res} = await this.$http.post('users',this.Addform)
						console.log(res)
						if (res.meta.status != 201){
							return this.$message.error(res.meta.msg)
						}
						// 创建成功后关闭对话框  不显示
						this.adddialogVisible = false
						this.$message.success(res.meta.msg)
						// 重新刷新(渲染页面)
						this.getUserList()
			}
</div>  


				<!-- echarts可视化图表-->
<div>
	1.  // ①导入echarts
		import * as echarts from 'echarts'
		// 导入lodash合并
		import _ from 'lodash'
	2.<el-card>
		<!--② 为 ECharts 准备一个具备大小（宽高）的 DOM -->
		<div id="main" style="width: 750px;height:400px;"></div>
	  </el-card>
	3.mounted(){
		//③ 基于准备好的dom，初始化echarts实例
		  var myChart = echarts.init(document.getElementById('main'));
	4. //准备数据和配置项  合并后的数据（请求数据和option数据合并）
			async mounted(){
				 const {data:res} = await this.$http.get('reports/type/1')
				 console.log(res)
				 if (res.meta.status !== 200) {
				   return this.$message.error('获取折线图数据失败！')
				 } 
				 <!-- 合并数据 -->
			 const result = _.merge(res.data,this.options)
	    option数据在data中
	5.//⑤ 使用刚指定的配置项和数据显示图表。
			 myChart.setOption(result);
</div>


